/*
============================================================================
Name        : dd_http.h
Author      : Jian (raphyer@hotmail.com)
Version     :
Copyright   : GPL
Description : dd_http.h - header file
============================================================================
*/


#ifndef __DD_HTTP_H__
#define __DD_HTTP_H__

#include "dd_define.h"
#include "sd_network.h"

__DD_BEGIN_DECLS

struct __dd_vector ;
struct __dd_post_fun ;
struct __dd_zip ;
typedef struct __dd_http dd_http ;

/* limit http 1.1 client implement for the simple client-server private protocol */

/* reqType of http */
enum {
    EHttpGet  = 0,
    EHttpPost, 
    EHttpHead,
    EHttpReqCount
};

typedef struct {
    int start ;
    int end ;   /* -1 mean the end of file */
} dd_http_range;

typedef struct {
    /* client pointer that used the http, find it back by http->callback.clientPtr */
    void* clientPtr ;

    /* before get/post data to server, you can do some job like add custom header to http */
    int (*start)(dd_http* http) ;
    
    /*
    * tell the http module if the http work was cancel
    * http module will call it multi-time before some blocking call 
    */ 
    int (*is_cancel)(const dd_http* http) ;

    /*
    * when the header is got finished, this function will call
    */
    int (*process_header)(const dd_http* http) ;

    /*
    *  offset: the offset of data in the whole body
    *  data:   get from server, len: the length of data
    *  return: < 0 error, == 0, send finished,  > 0 > send data length was set in the param data
    */
    int (*process_body)(const dd_http* http, const char* data, int offset, int len) ;
    
    /*
    * the http's work is finished, you can free the client memory here
    *  param: errorCode: == 0 mean succeed, < 0 mean failed
    */
    void (*finish)(const dd_http* http, int errorCode) ;

} dd_http_callback;


typedef struct {
    dd_http_callback    callback ;      /* set all to NULL mean you ignore all http event */
    DD_UTF8*            url ; 
    DD_UINT             port ; 
    struct __dd_vector* rangeVector ;   /* set rangeVector to NULL mean download all file */
} dd_http_req_get;


typedef struct {
    dd_http_callback  callback ;  /* set all to NULL mean you ignore all http event */
    DD_UTF8*          url ;
    DD_UINT           port ; 
    char*             buf ;
    int               bufLen ; 
} dd_http_req_post_buf;


typedef struct {
    dd_http_callback  callback ;    /* set all to NULL mean you ignore all http event */
    DD_UTF8*          url ;
    DD_UINT           port ;
    DD_UTF8*          fileName ;
} dd_http_req_post_file;


typedef struct {
    dd_http_callback    callback ;      /* set all to NULL mean you ignore all http event */
    DD_UTF8*            url ; 
    DD_UINT             port ; 
} dd_http_req_head ;



struct __dd_http {
    
    sd_socket*          tcp ;

    char*               host ;
    char*               address ;

    int                 reqType ;      /* only support get and post */ 
    struct __dd_vector* reqHeaders ;       
    
    struct __dd_post_fun* postDataFun ; 
    
    char*               respCode ;
    struct __dd_vector* respHeaders ;

    dd_http_callback    callback ;

    char*               buf ;
    int                 recvBufLen ;
    
    struct __dd_zip*    zip ;
    char*               unzipBuf ;
};

/* 
* below 4 get/post/head function is blocked until the http is finished 
* so you can not call it in your UI main thread
*/
int dd_http_get(const dd_http_req_get* req) ;

int dd_http_post_buffer(const dd_http_req_post_buf* req) ;

int dd_http_post_file(const dd_http_req_post_file* req) ;

int dd_http_head(const dd_http_req_head* req) ;

const char* dd_http_resp_code(const dd_http* http) ;

/* the return value is lower case */
const char* dd_http_get_req_header(const dd_http* http, const char* key) ;

/* the return value is lower case */
const char* dd_http_get_resp_header(const dd_http* http, const char* key) ;

void dd_http_add_req_header(dd_http* http, const char* key, const char* val) ;


__DD_END_DECLS	


#endif	/* __DD_HTTP_H__ */

/* End of File */
